package org.apache.lucene.index;

import java.io.IOException;

import org.apache.lucene.ocean.util.BytesPool;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Subclass of SegmentReader.  Pools the deleted docs BitVector byte array because
 * the Ocean system on each transaction clones the IndexReader and the deleted docs
 * byte array size is the same and so may be reused.
 */
public class OceanSegmentReader extends SegmentReader {
  final static Logger LOG = LoggerFactory.getLogger(OceanSegmentReader.class);
  private BytesPool bytesPool;

  public OceanSegmentReader() {
    bytesPool = BytesPool.getInstance();
    allowCloneWithChanges = true;
  }
  
  public synchronized void close(boolean flush) throws IOException {
    super.close(flush);
  }
  
  /**
   * Overridden to return the deletedDocs byte array to the bytePool
   */
  protected void doClose() throws IOException {
    // return deletedDocs bytes to bytesPool
    if (deletedDocs != null) {
      if (deletedDocsCopyOnWriteRef == null || deletedDocsCopyOnWriteRef.refCount() == 1) {
        bytesPool.returnObject(deletedDocs.getBits());
      }
    }
    super.doClose();
  }
  /**
  protected synchronized void decRef() throws IOException {
    if (getRefCount() == 1) {
      hasChanges = false;
    }
    super.decRef();
  }
  **/
  /**
  protected BitVector cloneDeletedDocs(BitVector deletedDocs) {
    byte[] bits = deletedDocs.getBits();
    byte[] cloneBits = bytesPool.getBytes(bits.length);
    System.arraycopy(bits, 0, cloneBits, 0, bits.length);
    BitVector cloned = new BitVector(cloneBits, deletedDocs.size(), -1);
    if (cloned.count() != deletedDocs.count()) {
      BitVector first = new BitVector(bits, deletedDocs.size(), -1);
      int firstCount = first.count();
      LOG.info("firstCount: "+firstCount+" cloned.count: "+cloned.count()+" deletedDocs.count: "+deletedDocs.count());
      assert cloned.count() == deletedDocs.count();
    }
    //
    return cloned;
  }
  **/
  /**
  public Object clone() {
    boolean origHasChanges = hasChanges;
    hasChanges = false;
    Object clone = super.clone();
    hasChanges = origHasChanges;
    return clone;
  }
  **/
  // TODO: need an in memory write lock that does not check the segment version
  /**
   * Overridden to keep the write lock from being written to disk as it is
   * unnecessary. 
   */
  protected void acquireWriteLock() throws IOException {
    //if (!isCurrent()) {
    //  throw new IOException("reader is not current");
    //}
  }
}
